package com.example.sbeducation.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * JWT工具类
 */
@Slf4j
@Component
public class JwtUtil {

  /**
   * JWT密钥
   */
  @Value("${jwt.secret:education_platform_jwt_secret_key_2023}")
  private String secret;

  /**
   * token有效期（毫秒），默认24小时
   */
  @Value("${jwt.expiration:86400000}")
  private long expiration;

  /**
   * 密钥对象，初始化后缓存，避免每次都重新创建
   */
  private SecretKey secretKey;

  /**
   * 初始化密钥
   */
  @PostConstruct
  public void init() {
    this.secretKey = Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8));
    log.info("JWT密钥已初始化");
  }

  /**
   * 获取密钥
   */
  private SecretKey getSecretKey() {
    return secretKey;
  }

  /**
   * 生成token
   * 
   * @param userId   用户ID
   * @param username 用户名
   * @param role     角色
   * @return token
   */
  public String generateToken(Long userId, String username, String role) {
    Map<String, Object> claims = new HashMap<>();
    claims.put("userId", userId);
    claims.put("username", username);
    claims.put("role", role);

    return Jwts.builder()
        .setClaims(claims)
        .setIssuedAt(new Date())
        .setExpiration(new Date(System.currentTimeMillis() + expiration))
        .signWith(getSecretKey(), SignatureAlgorithm.HS256)
        .compact();
  }

  /**
   * 解析token
   * 
   * @param token JWT token
   * @return Claims对象
   */
  public Claims parseToken(String token) {
    return Jwts.parserBuilder()
        .setSigningKey(getSecretKey())
        .build()
        .parseClaimsJws(token)
        .getBody();
  }

  /**
   * 获取用户ID
   * 
   * @param token JWT token
   * @return 用户ID
   */
  public Long getUserId(String token) {
    Claims claims = parseToken(token);
    return Long.parseLong(claims.get("userId").toString());
  }

  /**
   * 获取用户名
   * 
   * @param token JWT token
   * @return 用户名
   */
  public String getUsername(String token) {
    Claims claims = parseToken(token);
    return claims.get("username").toString();
  }

  /**
   * 获取用户角色
   * 
   * @param token JWT token
   * @return 用户角色
   */
  public String getRole(String token) {
    Claims claims = parseToken(token);
    return claims.get("role").toString();
  }

  /**
   * 验证token是否过期
   * 
   * @param token JWT token
   * @return 是否过期
   */
  public boolean isExpired(String token) {
    try {
      Claims claims = parseToken(token);
      Date expiration = claims.getExpiration();
      log.debug("Token过期时间:{}, 当前时间:{}", expiration, new Date());
      return expiration.before(new Date());
    } catch (Exception e) {
      log.error("Token解析失败", e);
      return true;
    }
  }
}